//一些对象方法的实现

const obj = {
    name: 'xn',
    age: 22,
    gender: '女'
}

// 1、entries
//用处：讲对象转成键值对数组
Object.prototype.sx_entries = function(obj){
    const res = []
    for(let key in obj){
        obj.hasOwnProperty(key) && res.push([key,obj[key]])
    }
    return res
}
console.log(Object.sx_entries(obj))


//2、fromEntries
//用处：跟entries相反，将键值对数组转成对象
Object.prototype.sx_fromEntries = function(arr){
    const obj = {}
    for(let i = 0; i < arr.length; i++){
        const [key,value] = arr[i]
        obj[key] = value
    }
    return obj
}
console.log(Object.sx_fromEntries([['name', '林三心'], ['age', 22], ['gender', '男']]))

//3、keys
//用处：将对象的key转成一个数组合集
Object.prototype.sx_keys = function(obj){
    const keys = []
    for(let key in obj){
        obj.hasOwnProperty(key) && keys.push(key)
    }
    return keys
}
console.log(Object.sx_keys(obj))

//4、values
//用处：将对象的所有值转成数组合集
Object.prototype.sx_values = function(obj){
    const values = []
    for(let key in obj){
        obj.hasOwnProperty(key) && values.push(obj[key])
    }
    return values
}
console.log(Object.sx_values(obj))

//5、instanceOf
//用处： A instanceOf B, 判断A是否经过B的原型链
function sx_instanceOf(obj,construct){
    let proto = obj._proto_
    while(proto){
        if(proto === construct.prototype){
            return true
        }
        proto = proto._proto_
    }
    return false
}
function Person(name){
    this.name = name
}
const sx = new Person('33')

console.log(sx_instanceOf(Person, sx)) // true



//6、is
//用处： Object.is(a,b),判断a是否等于b
Object.prototype.sx_is = function(x,y) {
    if(x === y){
        //防止 -0 和 +0
        return x !== 0 || 1 / x === 1 / y
    }
    //防止NaN
    return x !== x && y !== y
}

const a = { name: '33' }
const b = a
const c = { name: '33' }

console.log(Object.sx_is(a, b)) // true
console.log(Object.sx_is(a, c)) // false


//Object.assign
// 难点： assign 接收多个对象，并将多个对象合成一个对象
// 这些对象如果有重名属性，以后来的对象属性为准
//assign返回一个对象，这个对象 === 第一个对象
Object.prototype.sx_assign = function(target, ...args){
    if(target === null || target === undefined){
        throw new TypeError('Cannot convert undefined or null to object')
    }
    target = Object(target)

    for(let nextObj of args){
        for(let key in nextObj){
            nextObj.hasOwnProperty(key) && (target[key] = nextObj[key])
        }
    }

    return target
}